// XslTransformer.cs 
//
//  Copyright (C) 2008 Fullsix Marketing Interactivo LDA
//  Author: Marco Cecconi
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
//

// XslTransformHelper.cs created with MonoDevelop
// User: marco at 2:04 PM 11/3/2008
//

using System;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Xsl;

namespace SixPack.Xml.Xsl
{
    /// <summary>
    /// Encapsulates and extends an <see cref="XslCompiledTransform"/>.
    /// </summary>
    public class XslTransformer
    {
        private readonly XslCompiledTransform transform;

        /// <summary>
        /// Creates a new instance of the <see cref="XslTransformer"/> class.
        /// </summary>
        public XslTransformer()
        {
            transform = new XslCompiledTransform();
        }

        /// <summary>
        /// Creates a new instance of the <see cref="XslTransformer"/> class.
        /// </summary>
        /// <param name="transform">
        /// A <see cref="XslCompiledTransform"/> which will be used as a base for the transformation.
        /// </param>
        /// <exception cref="ArgumentNullException">The transform parameter is null.</exception>
        public XslTransformer(XslCompiledTransform transform)
        {
            if (transform == null)
                throw new ArgumentNullException("transform");

            this.transform = transform;
        }

        /// <value>
        /// Gets the current <see cref="XslCompiledTransform"/> generated by the class.
        /// </value>
        public XslCompiledTransform Xslt
        {
            get { return transform; }
        }

        /// <summary>
        /// Creates an XSLT transform from a string.
        /// </summary>
        /// <param name="xslt">
        /// A <see cref="System.String"/> containing the XSLT transformation.
        /// </param>
        /// <returns>
        /// Returns the current instance.
        /// </returns>
        /// <exception cref="ArgumentNullException">The "xsltAsString" parameter is null or empty.</exception>
        public XslTransformer FromString(string xslt)
        {
            if (string.IsNullOrEmpty(xslt))
                throw new ArgumentNullException("xslt");

            StringReader transformationXslt = new StringReader(xslt);
            transform.Load(new XmlTextReader(transformationXslt));
            return this;
        }

        /// <summary>
        /// Creates an XSLT transform from a resource.
        /// </summary>
        /// <param name="resourceName">
        /// The resource name from which to load the XSLT.
        /// </param>
        /// <param name="assembly">
        /// The <see cref="Assembly"/> containing the resource to be loaded.
        /// </param>
        /// <returns>
        /// Returns the current instance.
        /// </returns>
        /// <exception cref="ArgumentNullException">Either resourceName or assembly is null or empty.</exception>
        /// <exception cref="InvalidOperationException">The resource was not found in the specified assembly.</exception>
        public XslTransformer FromResource(string resourceName, Assembly assembly)
        {
            if (string.IsNullOrEmpty(resourceName))
                throw new ArgumentNullException("resourceName");

            if (assembly == null)
                throw new ArgumentNullException("assembly");

            using (Stream resource = assembly.GetManifestResourceStream(resourceName))
            {
                if (resource == null || !resource.CanRead)
                    throw new InvalidOperationException("Cannot find resource in specified assembly.");

                transform.Load(XmlReader.Create(resource));
                return this;
            }
        }

        /// <summary>
        /// Creates and XSLT transform from a resource
        /// </summary>
        /// <param name="resourceName">
        /// The resource name from which to load the XSLT.
        /// </param>
        /// <returns>
        /// Returns the current instance.
        /// </returns>
        /// <remarks>The resource is loaded form the calling assembly.</remarks>
        /// <exception cref="ArgumentNullException">Either resourceName or assembly is null or empty.</exception>
        /// <exception cref="InvalidOperationException">The resource was not found in the specified assembly.</exception>
        public XslTransformer FromResource(string resourceName)
        {
            return FromResource(resourceName, Assembly.GetCallingAssembly());
        }

        /// <summary>
        /// Creates and XSLT transform from a file
        /// </summary>
        /// <param name="fileName">
        /// The path of the file from which to load the XSLT.
        /// </param>
        /// <returns>
        /// Returns the current instance.
        /// </returns>
        /// <exception cref="ArgumentNullException">file name is null or empty.</exception>
        public XslTransformer FromFile(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                throw new ArgumentNullException("fileName");

            using (XmlReader xr = XmlReader.Create(File.OpenText(fileName)))
            {
                transform.Load(xr);
            }

            return this;
        }
    }
}
